package com.secret.chain.secretchain.solidity;

import org.fisco.bcos.sdk.abi.FunctionReturnDecoder;
import org.fisco.bcos.sdk.abi.TypeReference;
import org.fisco.bcos.sdk.abi.datatypes.Function;
import org.fisco.bcos.sdk.abi.datatypes.Type;
import org.fisco.bcos.sdk.abi.datatypes.Utf8String;
import org.fisco.bcos.sdk.abi.datatypes.generated.Uint256;
import org.fisco.bcos.sdk.abi.datatypes.generated.tuples.generated.Tuple7;
import org.fisco.bcos.sdk.client.Client;
import org.fisco.bcos.sdk.contract.Contract;
import org.fisco.bcos.sdk.crypto.CryptoSuite;
import org.fisco.bcos.sdk.crypto.keypair.CryptoKeyPair;
import org.fisco.bcos.sdk.model.CryptoType;
import org.fisco.bcos.sdk.model.TransactionReceipt;
import org.fisco.bcos.sdk.model.callback.TransactionCallback;
import org.fisco.bcos.sdk.transaction.model.exception.ContractException;

import java.math.BigInteger;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

@SuppressWarnings("unchecked")
public class Problem extends Contract {
    public static final String[] BINARY_ARRAY = {"608060405234801561001057600080fd5b5061062c806100206000396000f3fe608060405234801561001057600080fd5b50600436106100935760003560e01c8063913f56dc11610066578063913f56dc14610204578063a0f44c92146102fb578063a2e6204514610319578063b55c30f114610337578063efc81a8c1461035557610093565b8063200d2ed21461009857806332de6a41146100b65780636d4ce63c146100d45780638a4d5a6714610181575b600080fd5b6100a0610373565b6040518082815260200191505060405180910390f35b6100be610379565b6040518082815260200191505060405180910390f35b6100dc61037f565b6040518088815260200187815260200186815260200180602001858152602001848152602001838152602001828103825286818151815260200191508051906020019080838360005b83811015610140578082015181840152602081019050610125565b50505050905090810190601f16801561016d5780820380516001836020036101000a031916815260200191505b509850505050505050505060405180910390f35b610189610451565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156101c95780820151818401526020810190506101ae565b50505050905090810190601f1680156101f65780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6102f9600480360360e081101561021a57600080fd5b810190808035906020019092919080359060200190929190803590602001909291908035906020019064010000000081111561025557600080fd5b82018360208201111561026757600080fd5b8035906020019184600183028401116401000000008311171561028957600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192908035906020019092919080359060200190929190803590602001909291905050506104ef565b005b610303610539565b6040518082815260200191505060405180910390f35b61032161053f565b6040518082815260200191505060405180910390f35b61033f610545565b6040518082815260200191505060405180910390f35b61035d61054b565b6040518082815260200191505060405180910390f35b60045481565b60005481565b60008060006060600080600080546001546002546003600454600554600654838054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156104335780601f1061040857610100808354040283529160200191610433565b820191906000526020600020905b81548152906001019060200180831161041657829003601f168201915b50505050509350965096509650965096509650965090919293949596565b60038054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156104e75780601f106104bc576101008083540402835291602001916104e7565b820191906000526020600020905b8154815290600101906020018083116104ca57829003601f168201915b505050505081565b866000819055508560018190555084600281905550836003908051906020019061051a929190610551565b5082600481905550816005819055508060068190555050505050505050565b60025481565b60065481565b60015481565b60055481565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061059257805160ff19168380011785556105c0565b828001600101855582156105c0579182015b828111156105bf5782518255916020019190600101906105a4565b5b5090506105cd91906105d1565b5090565b6105f391905b808211156105ef5760008160009055506001016105d7565b5090565b9056fea26469706673582212209c46906882598653de0e2fcd9e94828516d21f15188b4e4cfceff261fede0d6564736f6c634300060a0033"};

    public static final String BINARY = org.fisco.bcos.sdk.utils.StringUtils.joinAll("", BINARY_ARRAY);

    public static final String[] SM_BINARY_ARRAY = {"608060405234801561001057600080fd5b5061062c806100206000396000f3fe608060405234801561001057600080fd5b50600436106100935760003560e01c8063913f56dc11610066578063913f56dc14610204578063a0f44c92146102fb578063a2e6204514610319578063b55c30f114610337578063efc81a8c1461035557610093565b8063200d2ed21461009857806332de6a41146100b65780636d4ce63c146100d45780638a4d5a6714610181575b600080fd5b6100a0610373565b6040518082815260200191505060405180910390f35b6100be610379565b6040518082815260200191505060405180910390f35b6100dc61037f565b6040518088815260200187815260200186815260200180602001858152602001848152602001838152602001828103825286818151815260200191508051906020019080838360005b83811015610140578082015181840152602081019050610125565b50505050905090810190601f16801561016d5780820380516001836020036101000a031916815260200191505b509850505050505050505060405180910390f35b610189610451565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156101c95780820151818401526020810190506101ae565b50505050905090810190601f1680156101f65780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6102f9600480360360e081101561021a57600080fd5b810190808035906020019092919080359060200190929190803590602001909291908035906020019064010000000081111561025557600080fd5b82018360208201111561026757600080fd5b8035906020019184600183028401116401000000008311171561028957600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192908035906020019092919080359060200190929190803590602001909291905050506104ef565b005b610303610539565b6040518082815260200191505060405180910390f35b61032161053f565b6040518082815260200191505060405180910390f35b61033f610545565b6040518082815260200191505060405180910390f35b61035d61054b565b6040518082815260200191505060405180910390f35b60045481565b60005481565b60008060006060600080600080546001546002546003600454600554600654838054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156104335780601f1061040857610100808354040283529160200191610433565b820191906000526020600020905b81548152906001019060200180831161041657829003601f168201915b50505050509350965096509650965096509650965090919293949596565b60038054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156104e75780601f106104bc576101008083540402835291602001916104e7565b820191906000526020600020905b8154815290600101906020018083116104ca57829003601f168201915b505050505081565b866000819055508560018190555084600281905550836003908051906020019061051a929190610551565b5082600481905550816005819055508060068190555050505050505050565b60025481565b60065481565b60015481565b60055481565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061059257805160ff19168380011785556105c0565b828001600101855582156105c0579182015b828111156105bf5782518255916020019190600101906105a4565b5b5090506105cd91906105d1565b5090565b6105f391905b808211156105ef5760008160009055506001016105d7565b5090565b9056fea26469706673582212209c46906882598653de0e2fcd9e94828516d21f15188b4e4cfceff261fede0d6564736f6c634300060a0033"};

    public static final String SM_BINARY = org.fisco.bcos.sdk.utils.StringUtils.joinAll("", SM_BINARY_ARRAY);

    public static final String[] ABI_ARRAY = {"[{\"name\":\"answerId\",\"type\":\"function\",\"constant\":true,\"payable\":false,\"anonymous\":false,\"stateMutability\":\"view\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"indexed\":false,\"components\":null,\"typeAsString\":\"uint256\"}],\"methodSignatureAsString\":\"answerId()\"},{\"name\":\"askId\",\"type\":\"function\",\"constant\":true,\"payable\":false,\"anonymous\":false,\"stateMutability\":\"view\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"indexed\":false,\"components\":null,\"typeAsString\":\"uint256\"}],\"methodSignatureAsString\":\"askId()\"},{\"name\":\"content\",\"type\":\"function\",\"constant\":true,\"payable\":false,\"anonymous\":false,\"stateMutability\":\"view\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"string\",\"indexed\":false,\"components\":null,\"typeAsString\":\"string\"}],\"methodSignatureAsString\":\"content()\"},{\"name\":\"create\",\"type\":\"function\",\"constant\":true,\"payable\":false,\"anonymous\":false,\"stateMutability\":\"view\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"indexed\":false,\"components\":null,\"typeAsString\":\"uint256\"}],\"methodSignatureAsString\":\"create()\"},{\"name\":\"get\",\"type\":\"function\",\"constant\":true,\"payable\":false,\"anonymous\":false,\"stateMutability\":\"view\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"indexed\":false,\"components\":null,\"typeAsString\":\"uint256\"},{\"name\":\"\",\"type\":\"uint256\",\"indexed\":false,\"components\":null,\"typeAsString\":\"uint256\"},{\"name\":\"\",\"type\":\"uint256\",\"indexed\":false,\"components\":null,\"typeAsString\":\"uint256\"},{\"name\":\"\",\"type\":\"string\",\"indexed\":false,\"components\":null,\"typeAsString\":\"string\"},{\"name\":\"\",\"type\":\"uint256\",\"indexed\":false,\"components\":null,\"typeAsString\":\"uint256\"},{\"name\":\"\",\"type\":\"uint256\",\"indexed\":false,\"components\":null,\"typeAsString\":\"uint256\"},{\"name\":\"\",\"type\":\"uint256\",\"indexed\":false,\"components\":null,\"typeAsString\":\"uint256\"}],\"methodSignatureAsString\":\"get()\"},{\"name\":\"groupId\",\"type\":\"function\",\"constant\":true,\"payable\":false,\"anonymous\":false,\"stateMutability\":\"view\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"indexed\":false,\"components\":null,\"typeAsString\":\"uint256\"}],\"methodSignatureAsString\":\"groupId()\"},{\"name\":\"set\",\"type\":\"function\",\"constant\":false,\"payable\":false,\"anonymous\":false,\"stateMutability\":\"nonpayable\",\"inputs\":[{\"name\":\"_askId\",\"type\":\"uint256\",\"indexed\":false,\"components\":null,\"typeAsString\":\"uint256\"},{\"name\":\"_answerId\",\"type\":\"uint256\",\"indexed\":false,\"components\":null,\"typeAsString\":\"uint256\"},{\"name\":\"_groupId\",\"type\":\"uint256\",\"indexed\":false,\"components\":null,\"typeAsString\":\"uint256\"},{\"name\":\"_content\",\"type\":\"string\",\"indexed\":false,\"components\":null,\"typeAsString\":\"string\"},{\"name\":\"_status\",\"type\":\"uint256\",\"indexed\":false,\"components\":null,\"typeAsString\":\"uint256\"},{\"name\":\"_create\",\"type\":\"uint256\",\"indexed\":false,\"components\":null,\"typeAsString\":\"uint256\"},{\"name\":\"_update\",\"type\":\"uint256\",\"indexed\":false,\"components\":null,\"typeAsString\":\"uint256\"}],\"outputs\":[],\"methodSignatureAsString\":\"set(uint256,uint256,uint256,string,uint256,uint256,uint256)\"},{\"name\":\"status\",\"type\":\"function\",\"constant\":true,\"payable\":false,\"anonymous\":false,\"stateMutability\":\"view\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"indexed\":false,\"components\":null,\"typeAsString\":\"uint256\"}],\"methodSignatureAsString\":\"status()\"},{\"name\":\"update\",\"type\":\"function\",\"constant\":true,\"payable\":false,\"anonymous\":false,\"stateMutability\":\"view\",\"inputs\":[],\"outputs\":[{\"name\":\"\",\"type\":\"uint256\",\"indexed\":false,\"components\":null,\"typeAsString\":\"uint256\"}],\"methodSignatureAsString\":\"update()\"}]"};

    public static final String ABI = org.fisco.bcos.sdk.utils.StringUtils.joinAll("", ABI_ARRAY);

    public static final String FUNC_ANSWERID = "answerId";

    public static final String FUNC_ASKID = "askId";

    public static final String FUNC_CONTENT = "content";

    public static final String FUNC_CREATE = "create";

    public static final String FUNC_GET = "get";

    public static final String FUNC_GROUPID = "groupId";

    public static final String FUNC_SET = "set";

    public static final String FUNC_STATUS = "status";

    public static final String FUNC_UPDATE = "update";

    protected Problem(String contractAddress, Client client, CryptoKeyPair credential) {
        super(getBinary(client.getCryptoSuite()), contractAddress, client, credential);
    }

    public static String getBinary(CryptoSuite cryptoSuite) {
        return (cryptoSuite.getCryptoTypeConfig() == CryptoType.ECDSA_TYPE ? BINARY : SM_BINARY);
    }

    public BigInteger answerId() throws ContractException {
        final Function function = new Function(FUNC_ANSWERID, 
                Arrays.<Type>asList(), 
                Arrays.<TypeReference<?>>asList(new TypeReference<Uint256>() {}));
        return executeCallWithSingleValueReturn(function, BigInteger.class);
    }

    public BigInteger askId() throws ContractException {
        final Function function = new Function(FUNC_ASKID, 
                Arrays.<Type>asList(), 
                Arrays.<TypeReference<?>>asList(new TypeReference<Uint256>() {}));
        return executeCallWithSingleValueReturn(function, BigInteger.class);
    }

    public String content() throws ContractException {
        final Function function = new Function(FUNC_CONTENT, 
                Arrays.<Type>asList(), 
                Arrays.<TypeReference<?>>asList(new TypeReference<Utf8String>() {}));
        return executeCallWithSingleValueReturn(function, String.class);
    }

    public BigInteger create() throws ContractException {
        final Function function = new Function(FUNC_CREATE, 
                Arrays.<Type>asList(), 
                Arrays.<TypeReference<?>>asList(new TypeReference<Uint256>() {}));
        return executeCallWithSingleValueReturn(function, BigInteger.class);
    }

    public Tuple7<BigInteger, BigInteger, BigInteger, String, BigInteger, BigInteger, BigInteger> get() throws ContractException {
        final Function function = new Function(FUNC_GET, 
                Arrays.<Type>asList(), 
                Arrays.<TypeReference<?>>asList(new TypeReference<Uint256>() {}, new TypeReference<Uint256>() {}, new TypeReference<Uint256>() {}, new TypeReference<Utf8String>() {}, new TypeReference<Uint256>() {}, new TypeReference<Uint256>() {}, new TypeReference<Uint256>() {}));
        List<Type> results = executeCallWithMultipleValueReturn(function);
        return new Tuple7<BigInteger, BigInteger, BigInteger, String, BigInteger, BigInteger, BigInteger>(
                (BigInteger) results.get(0).getValue(), 
                (BigInteger) results.get(1).getValue(), 
                (BigInteger) results.get(2).getValue(), 
                (String) results.get(3).getValue(), 
                (BigInteger) results.get(4).getValue(), 
                (BigInteger) results.get(5).getValue(), 
                (BigInteger) results.get(6).getValue());
    }

    public BigInteger groupId() throws ContractException {
        final Function function = new Function(FUNC_GROUPID, 
                Arrays.<Type>asList(), 
                Arrays.<TypeReference<?>>asList(new TypeReference<Uint256>() {}));
        return executeCallWithSingleValueReturn(function, BigInteger.class);
    }

    public TransactionReceipt set(BigInteger _askId, BigInteger _answerId, BigInteger _groupId, String _content, BigInteger _status, BigInteger _create, BigInteger _update) {
        final Function function = new Function(
                FUNC_SET, 
                Arrays.<Type>asList(new Uint256(_askId),
                new Uint256(_answerId),
                new Uint256(_groupId),
                new Utf8String(_content),
                new Uint256(_status),
                new Uint256(_create),
                new Uint256(_update)),
                Collections.<TypeReference<?>>emptyList());
        return executeTransaction(function);
    }

    public void set(BigInteger _askId, BigInteger _answerId, BigInteger _groupId, String _content, BigInteger _status, BigInteger _create, BigInteger _update, TransactionCallback callback) {
        final Function function = new Function(
                FUNC_SET, 
                Arrays.<Type>asList(new Uint256(_askId),
                new Uint256(_answerId),
                new Uint256(_groupId),
                new Utf8String(_content),
                new Uint256(_status),
                new Uint256(_create),
                new Uint256(_update)),
                Collections.<TypeReference<?>>emptyList());
        asyncExecuteTransaction(function, callback);
    }

    public String getSignedTransactionForSet(BigInteger _askId, BigInteger _answerId, BigInteger _groupId, String _content, BigInteger _status, BigInteger _create, BigInteger _update) {
        final Function function = new Function(
                FUNC_SET, 
                Arrays.<Type>asList(new Uint256(_askId),
                new Uint256(_answerId),
                new Uint256(_groupId),
                new Utf8String(_content),
                new Uint256(_status),
                new Uint256(_create),
                new Uint256(_update)),
                Collections.<TypeReference<?>>emptyList());
        return createSignedTransaction(function);
    }

    public Tuple7<BigInteger, BigInteger, BigInteger, String, BigInteger, BigInteger, BigInteger> getSetInput(TransactionReceipt transactionReceipt) {
        String data = transactionReceipt.getInput().substring(10);
        final Function function = new Function(FUNC_SET, 
                Arrays.<Type>asList(), 
                Arrays.<TypeReference<?>>asList(new TypeReference<Uint256>() {}, new TypeReference<Uint256>() {}, new TypeReference<Uint256>() {}, new TypeReference<Utf8String>() {}, new TypeReference<Uint256>() {}, new TypeReference<Uint256>() {}, new TypeReference<Uint256>() {}));
        List<Type> results = FunctionReturnDecoder.decode(data, function.getOutputParameters());
        return new Tuple7<BigInteger, BigInteger, BigInteger, String, BigInteger, BigInteger, BigInteger>(

                (BigInteger) results.get(0).getValue(), 
                (BigInteger) results.get(1).getValue(), 
                (BigInteger) results.get(2).getValue(), 
                (String) results.get(3).getValue(), 
                (BigInteger) results.get(4).getValue(), 
                (BigInteger) results.get(5).getValue(), 
                (BigInteger) results.get(6).getValue()
                );
    }

    public BigInteger status() throws ContractException {
        final Function function = new Function(FUNC_STATUS, 
                Arrays.<Type>asList(), 
                Arrays.<TypeReference<?>>asList(new TypeReference<Uint256>() {}));
        return executeCallWithSingleValueReturn(function, BigInteger.class);
    }

    public BigInteger update() throws ContractException {
        final Function function = new Function(FUNC_UPDATE, 
                Arrays.<Type>asList(), 
                Arrays.<TypeReference<?>>asList(new TypeReference<Uint256>() {}));
        return executeCallWithSingleValueReturn(function, BigInteger.class);
    }

    public static Problem load(String contractAddress, Client client, CryptoKeyPair credential) {
        return new Problem(contractAddress, client, credential);
    }

    public static Problem deploy(Client client, CryptoKeyPair credential) throws ContractException {
        return deploy(Problem.class, client, credential, getBinary(client.getCryptoSuite()), "");
    }
}
